package com.ruoyi.web.controller.system;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiGettokenRequest;
import com.dingtalk.api.request.OapiUserGetRequest;
import com.dingtalk.api.request.OapiUserGetuserinfoRequest;
import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiUserGetResponse;
import com.dingtalk.api.response.OapiUserGetuserinfoResponse;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.*;
import com.ruoyi.dingtalk.config.UrlConstant;
import com.ruoyi.dingtalk.domain.UserInfoDTO;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.service.*;
import com.ruoyi.weixin.mp.entity.MsgTemplate;
import com.taobao.api.ApiException;
import net.sf.json.JSONArray;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.ruoyi.common.utils.HttpClientUtil.doGet;
import static com.ruoyi.common.utils.HttpClientUtil.doPost;

/**
 * 登录验证
 *
 * @author ruoyi
 */
@RestController
public class SysLoginController
{

	@Autowired
	private UsersService usersService;

	@Autowired
	private UserAuthsService userAuthsService;

	@Autowired
	private ISysUserRoleService userRoleService;

	@Autowired
	private ISysUserDeptService userDeptService;

    @Autowired
    private SysLoginService loginService;

    @Autowired
    private ISysMenuService menuService;

    @Autowired
    private SysPermissionService permissionService;

	@Autowired
	private ISysUserService sysUserService;

    @Autowired
    private TokenService tokenService;

	@Autowired
	private JwtTokenUtil jwtTokenUtil;

	@Autowired
	private Gitee gitee;

	@Autowired
	private Github github;

	@Autowired
	private Dingtalk dingtalk;

	private final static String USER_ID = "userId";

	//默认图片地址
	private final static String AVATAR_URL = "https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif";


	/**
     * 登录方法
     *
     * @param loginBody 登录信息
     * @return 结果
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody LoginBody loginBody)
    {
		Map<String,Object> ajax = new HashMap<>();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid());
        ajax.put(Constants.TOKEN, token);
        return AjaxResult.success(ajax);
    }

	/**
     * 获取用户信息
     *
     * @return 用户信息
     */
    @GetMapping("getInfo")
    public AjaxResult getInfo()
    {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        SysUser user = loginUser.getUser();
        // 角色集合
        Set<String> roles = permissionService.getRolePermission(user);
        // 权限集合
        Set<String> permissions = permissionService.getMenuPermission(user);
		Map<String,Object> ajax = new HashMap<>(16);
        ajax.put("user", user);
        ajax.put("roles", roles);
        ajax.put("permissions", permissions);
        return AjaxResult.success(ajax);
    }

    /**
     * 获取路由信息
     *
     * @return 路由信息
     */
    @GetMapping("getRouters")
    public AjaxResult getRouters()
    {
        LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
        // 用户信息
        SysUser user = loginUser.getUser();
        List<SysMenu> menus = menuService.selectMenuTreeByUserId(user.getUserId());
        return AjaxResult.success(menuService.buildMenus(menus));
    }

	/**
	 * 根据code以及登陆方式，获取token以及user信息，并返回前端
	 * @param code
	 * @return
	 */
	@GetMapping("/githubauth")
	@Transactional
	public AjaxResult githubauth(@RequestParam String code, @RequestParam String state,@RequestParam String uuid) throws ApiException {
		String token = "";
		String auth = "";
		String responseStr = "";
		String str = "";
		Map<String, String> map = new HashMap<>(16);
		SysUser sysUser = null;
		JSONObject jsonObject = null;
		if (state.equals(github.getState())) {
			auth = "github";
			map.put("client_id", github.getClientId());
			map.put("client_secret", github.getClientSecret());
			map.put("redirect_uri", github.getRedirectUri());
			map.put("code", code);
			map.put("state", github.getState());
			responseStr = doGet(github.getTokenUri(), map);
			Map<String, String> map1 = stringToMap(responseStr);
			token = map1.get("access_token");
			str = doGet(github.getUserUri(), map1);
		} else if (state.equals(gitee.getState())) {
			auth = "gitee";
			map.put("client_id", gitee.getClientId());
			map.put("client_secret",gitee.getClientSecret());
			map.put("redirect_uri", gitee.getRedirectUri());
			map.put("code", code);
			map.put("state", gitee.getState());
			map.put("grant_type", "authorization_code");
			responseStr = doPost(gitee.getTokenUri(), map);
			jsonObject = JSONObject.parseObject(responseStr);
			Map<String, String> map1 = new HashMap<>(16);
			token = jsonObject.getString("access_token");
			map1.put("access_token", token);
			str = doGet(gitee.getUserUri(), map1);
		} else if (state.equals(dingtalk.getState())){
			auth="dingtalk";
			//  获取token
			DefaultDingTalkClient client = new DefaultDingTalkClient(UrlConstant.URL_GET_TOKEN);
			OapiGettokenRequest request = new OapiGettokenRequest();
			request.setAppkey(dingtalk.getAppKey());
			request.setAppsecret(dingtalk.getAppSecret());
			request.setHttpMethod("GET");
			OapiGettokenResponse response= client.execute(request);
			// 获取UserId
			DingTalkClient client1 = new DefaultDingTalkClient(UrlConstant.URL_GET_USER_INFO);
			OapiUserGetuserinfoRequest request1 = new OapiUserGetuserinfoRequest();
			request1.setCode(code);
			request1.setHttpMethod("GET");
			OapiUserGetuserinfoResponse response1 = client1.execute(request1, response.getAccessToken());
			// 根据UserId获取用户信息
			DingTalkClient client2 = new DefaultDingTalkClient(UrlConstant.URL_USER_GET);
			OapiUserGetRequest request2 = new OapiUserGetRequest();
			request2.setUserid(response1.getUserid());
			request2.setHttpMethod("GET");
			OapiUserGetResponse response2 = client2.execute(request2, response.getAccessToken());
			str=response2.getBody().toString();
		} else {
			return AjaxResult.error();
		}

		jsonObject = JSONObject.parseObject(str);
		if (jsonObject == null) {
			return AjaxResult.error();
		}
		if ("dingtalk".equals(auth)) {
			LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<SysUser>()
				.eq(SysUser::getPhonenumber, jsonObject.getString("mobile"))
				.eq(SysUser::getUserAuthsUserId, jsonObject.getString("userid"))
				.eq(SysUser::getIdentityType, "dingtalk");
			sysUser = sysUserService.getOne(wrapper);
		}else {
			sysUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>()
				.eq(SysUser::getUserAuthsUserId, jsonObject.getString("id")));
		}
		if (sysUser == null) {
			UserInfoDTO userInfoDTO=new UserInfoDTO();
			userInfoDTO.setUserid(jsonObject.getString("id"));
			userInfoDTO.setUserName(jsonObject.getString("login"));
			userInfoDTO.setNickName(jsonObject.getString("name"));
			userInfoDTO.setRemark("由"+auth+"接口加入用户");
			if (!state.equals(dingtalk.getState())) {
				userInfoDTO.setAvatar(jsonObject.getString("avatar_url"));
				saveUser(userInfoDTO,auth);
			} else {
				userInfoDTO.setAvatar(jsonObject.getString("avatar"));
				saveUser(userInfoDTO,auth);
			}
			token = loginService.login(jsonObject.getString("login"), "123456", "authLogin", uuid);
			//loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),loginBody.getUuid());
		}else {
			Map<String,Object> ajax = new HashMap<>(16);
			// 生成令牌
			token = loginService.login(sysUser.getUserName(),"123456","authLogin",uuid);
			ajax.put(Constants.TOKEN, token);
			return AjaxResult.success(ajax);
		}
		Map<String, Object> ajax = new HashMap<String,Object>(16);
		ajax.put(Constants.TOKEN, token);
		return AjaxResult.success(ajax);
	}

	/**
	 * 传入userinfodto新增用户
	 * @param userInfoDTO
	 */
	protected void saveUser(UserInfoDTO userInfoDTO,String identityType){
		// 保存用户表
		SysUser sysUser = new SysUser();
		sysUser.setUserAuthsUserId(userInfoDTO.getUserid());
		sysUser.setUserName(userInfoDTO.getUserName());
		sysUser.setNickName(userInfoDTO.getNickName());
		sysUser.setPassword(SecurityUtils.encryptPassword("123456"));
		sysUser.setAvatar(userInfoDTO.getAvatar());
		sysUser.setIdentityType(identityType);
		//默认为普通员工
		sysUser.setDeptId(4L);
		sysUserService.save(sysUser);
		// 保存第三方用户表
		UserAuths userAuths = new UserAuths();
		userAuths.setUserId(sysUser.getUserId());
		userAuths.setIdentifier(userInfoDTO.getMobile());
		userAuths.setIdentityType(identityType);
		userAuths.setMobil(userInfoDTO.getMobile());
		userAuths.setCredential(String.valueOf(userInfoDTO.getOpenId()));
		userAuthsService.save(userAuths);
		// 保存默认权限表
		SysUserRole userRole = new SysUserRole();
		userRole.setUserId(userAuths.getUserId());
		userRole.setRoleId(RoleUtil.getDefaultRoleId());
		userRoleService.save(userRole);
		// 保存默认部门表
		SysUserDept userDept  = new SysUserDept();
		userDept.setUserId(userAuths.getUserId());
		userDept.setDeptId(DeptUtil.getDefaultDeptId());
		userDeptService.save(userDept);
	}

	/**
	 * String转MAP
	 * @param params
	 * @return
	 */
	protected Map<String, String> stringToMap(String params) {
		String aa = params.substring(params.lastIndexOf("?") + 1, params.length());
		String[] bb = aa.split("&");
		String cc = null;
		String[] dd = null;
		String key = null;
		String value = null;
		Map<String, String> map = new HashMap<String, String>(16);
		for (String s : bb) {
			String[] s1 = s.split("=");
			JSONArray js = JSONArray.fromObject(s1);
			if (js.size() > 1) {
				key = (String) js.get(0);
				value = (String) js.get(1);
				map.put(key, value);
			}
		}
		return map;
	}


}
